Add gdk_screen_get_primary_monitor(). This fixes bug #601712
authorCody Russell <bratsche@gnome.org>
Tue, 8 Dec 2009 17:27:02 +0000 (11:27 -0600)
committerCody Russell <bratsche@gnome.org>
Tue, 8 Dec 2009 17:27:02 +0000 (11:27 -0600)
gdk/gdkscreen.h
gdk/x11/gdkscreen-x11.c
gdk/x11/gdkscreen-x11.h
tests/testxinerama.c

index 96ff8d44a2f112ac7194f2fc28111ddaeae2681e..4e3bb1c713a5e5514011aaae02c49c8a48818d4f 100644 (file)
@@ -91,6 +91,7 @@ GList *      gdk_screen_get_toplevel_windows  (GdkScreen   *screen);
 gchar *      gdk_screen_make_display_name     (GdkScreen   *screen);
 
 gint          gdk_screen_get_n_monitors        (GdkScreen *screen);
+gint          gdk_screen_get_primary_monitor   (GdkScreen *screen);
 void          gdk_screen_get_monitor_geometry  (GdkScreen *screen,
                                                gint       monitor_num,
                                                GdkRectangle *dest);
index 987bcfca7ee264ad62e30f89cb3d924c31db335f..3e7b8b9067a0d204a17aea72be3c7fba6f6d4a86 100644 (file)
@@ -354,6 +354,31 @@ gdk_screen_get_n_monitors (GdkScreen *screen)
   return GDK_SCREEN_X11 (screen)->n_monitors;
 }
 
+/**
+ * gdk_screen_get_primary_monitor:
+ * @screen: a #GdkScreen.
+ *
+ * Gets the primary monitor for @screen.  The primary monitor
+ * is considered the monitor where the 'main desktop' lives.
+ * While normal application windows typically allow the window
+ * manager to place the windows, specialized desktop applications
+ * such as panels should place themselves on the primary monitor.
+ *
+ * If no primary monitor is configured by the user, the return value
+ * will be 0, defaulting to the first monitor.
+ *
+ * Returns: An integer index for the primary monitor, or 0 if none is configured.
+ *
+ * Since: 2.20
+ */
+gint
+gdk_screen_get_primary_monitor (GdkScreen *screen)
+{
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), 0);
+
+  return GDK_SCREEN_X11 (screen)->primary_monitor;
+}
+
 /**
  * gdk_screen_get_monitor_width_mm:
  * @screen: a #GdkScreen
@@ -722,6 +747,7 @@ init_randr13 (GdkScreen *screen)
   GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
   Display *dpy = GDK_SCREEN_XDISPLAY (screen);
   XRRScreenResources *resources;
+  RROutput primary_output;
   int i;
   GArray *monitors;
   gboolean randr12_compat = FALSE;
@@ -733,15 +759,23 @@ init_randr13 (GdkScreen *screen)
                                            screen_x11->xroot_window);
   if (!resources)
     return FALSE;
-  
+
   monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor),
                                 resources->noutput);
 
+  primary_output = XRRGetOutputPrimary (screen_x11->xdisplay,
+                                        screen_x11->xroot_window);
+
   for (i = 0; i < resources->noutput; ++i)
     {
       XRROutputInfo *output =
        XRRGetOutputInfo (dpy, resources, resources->outputs[i]);
 
+      if (resources->outputs[i] == primary_output)
+        {
+          screen_x11->primary_monitor = i;
+        }
+
       /* Non RandR1.2 X driver have output name "default" */
       randr12_compat |= !g_strcmp0(output->name, "default");
 
@@ -1110,7 +1144,10 @@ _gdk_x11_screen_size_changed (GdkScreen *screen,
   display_x11 = GDK_DISPLAY_X11 (gdk_screen_get_display (screen));
 
   if (display_x11->have_randr13 && event->type == ConfigureNotify)
-    return;
+    {
+      g_signal_emit_by_name (screen, "monitors-changed");
+      return;
+    }
 
   XRRUpdateConfiguration (event);
 #else
index 0d1548cdbbb9925b21bb9645d8ee5233c6fdde7b..3efee6ac9e22e857e834306ae7310f88f49c65f2 100644 (file)
@@ -93,6 +93,7 @@ struct _GdkScreenX11
   /* Xinerama/RandR 1.2 */
   gint          n_monitors;
   GdkX11Monitor        *monitors;
+  gint           primary_monitor;
 
   /* Pango renderer object singleton */
   PangoRenderer *renderer;
index 56dcde3f6e5a56a59a2361ec81b88c8b33e4ecdb..d9d37a9f4e6b0002809a1b82551b2a04945c8900 100644 (file)
 #include <gtk/gtk.h>
 
 static gint num_monitors;
+static gint primary_monitor;
 
 static void
 request (GtkWidget      *widget,
         gpointer        user_data)
 {
   gchar *str;
-  gint i = gdk_screen_get_monitor_at_window (gtk_widget_get_screen (widget),
+  GdkScreen *screen = gtk_widget_get_screen (widget);
+  gint i = gdk_screen_get_monitor_at_window (screen,
                                             widget->window);
 
   if (i < 0)
@@ -37,18 +39,35 @@ request (GtkWidget      *widget,
   else
     {
       GdkRectangle monitor;
-      gdk_screen_get_monitor_geometry (gtk_widget_get_screen (widget), i, &monitor);
+
+      gdk_screen_get_monitor_geometry (screen,
+                                       i, &monitor);
+      primary_monitor = gdk_screen_get_primary_monitor (screen);
+
       str = g_strdup_printf ("<big><span foreground='white' background='black'>"
                             "Monitor %d of %d</span></big>\n"
                             "<i>Width - Height       </i>: (%d,%d)\n"
-                            "<i>Top left coordinate </i>: (%d,%d)",i+1, num_monitors,
-                            monitor.width, monitor.height, monitor.x, monitor.y);
+                            "<i>Top left coordinate </i>: (%d,%d)\n"
+                             "<i>Primary monitor: %d</i>",
+                             i + 1, num_monitors,
+                            monitor.width, monitor.height,
+                             monitor.x, monitor.y,
+                             primary_monitor);
     }
-  
+
   gtk_label_set_markup (GTK_LABEL (user_data), str);
   g_free (str);
 }
 
+static void
+monitors_changed_cb (GdkScreen *screen,
+                     gpointer   data)
+{
+  GtkWidget *label = (GtkWidget *)data;
+
+  request (label, label);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -63,8 +82,10 @@ main (int argc, char *argv[])
   num_monitors = gdk_screen_get_n_monitors (screen);
   if (num_monitors == 1)
     g_warning ("The default screen of the current display only has one monitor.");
-  
-  for (i=0; i<num_monitors; i++)
+
+  primary_monitor = gdk_screen_get_primary_monitor (screen);
+
+  for (i = 0; i < num_monitors; i++)
     {
       GdkRectangle monitor; 
       gchar *str;
@@ -80,8 +101,12 @@ main (int argc, char *argv[])
       str = g_strdup_printf ("<big><span foreground='white' background='black'>"
                             "Monitor %d of %d</span></big>\n"
                             "<i>Width - Height       </i>: (%d,%d)\n"
-                            "<i>Top left coordinate </i>: (%d,%d)",i+1, num_monitors,
-                            monitor.width, monitor.height, monitor.x, monitor.y);
+                            "<i>Top left coordinate </i>: (%d,%d)\n"
+                             "<i>Primary monitor: %d</i>",
+                             i + 1, num_monitors,
+                            monitor.width, monitor.height,
+                             monitor.x, monitor.y,
+                             primary_monitor);
       gtk_label_set_markup (GTK_LABEL (label), str);
       g_free (str);
       vbox = gtk_vbox_new (TRUE, 1);
@@ -94,8 +119,11 @@ main (int argc, char *argv[])
       g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
       gtk_container_add (GTK_CONTAINER (vbox), button);
       gtk_widget_show_all (window);
+
+      g_signal_connect (screen, "monitors-changed",
+                        G_CALLBACK (monitors_changed_cb), label);
     }
-  
+
   gtk_main ();
 
   return 0;